// Bachelor of Software Engineering 
// Media Design School 
// Auckland
// New Zealand
// 
// (c) 2005 - 2014 Media Design School 
// 
// File Name : Vector2.cpp
// Description : Vector2 implementation
// Author : Serge Radinovich
// Mail : srad015@hotmail.com

#pragma once
#include "Vector2.h"

///////////////////////////////////////////////////////////////////////////////
// inline functions for Vector2
///////////////////////////////////////////////////////////////////////////////
Vector2 Vector2::operator-() const 
{
    return Vector2(-x, -y);
}

Vector2 Vector2::operator+(const Vector2& _krRHS) const 
{
    return Vector2(x+_krRHS.x, y+_krRHS.y);
}


Vector2 Vector2::operator-(const Vector2& _krRHS) const 
{
    return Vector2(x-_krRHS.x, y-_krRHS.y);
}

Vector2& Vector2::operator+=(const Vector2& _krRHS) 
{
    x += _krRHS.x; y += _krRHS.y; return *this;
}

Vector2& Vector2::operator-=(const Vector2& _krRHS) 
{
    x -= _krRHS.x; y -= _krRHS.y; return *this;
}

Vector2 Vector2::operator*(const int _kiA) const 
{
    return Vector2(this->x*_kiA, this->y*_kiA);
}

Vector2 operator*(const int _kiScale, const Vector2& _krVec)
{
	return Vector2(_krVec.x * _kiScale, _krVec.y * _kiScale);
}

Vector2 Vector2::operator*(const Vector2& _kRHS) const 
{
    return Vector2(this->x * _kRHS.x, this->y * _kRHS.y);
}

Vector2& Vector2::operator*=(const int _kiA) 
{
    this->x *= _kiA; this->y *= _kiA; return *this;
}

Vector2& Vector2::operator*=(const Vector2& _krVec) 
{
    this->x *= _krVec.x; this->y *= _krVec.y; return *this;
}

Vector2 Vector2::operator/(const int _kiA) const 
{
    return Vector2(this->x/_kiA, this->y/_kiA);
}

Vector2& Vector2::operator/=(const int _kiA) 
{
    this->x /= _kiA; this->y /=_kiA; return *this;
}

bool Vector2::operator==(const Vector2& _krRHS) const 
{
    return (x == _krRHS.x) && (y == _krRHS.y);
}

bool Vector2::operator!=(const Vector2& _krRHS) const 
{
    return (x != _krRHS.x) || (y != _krRHS.y);
}

int Vector2::Magnitude() const 
{
	float _fSqr = static_cast<float>(x*x + y*y);
	return static_cast<int>(sqrtf(_fSqr));

}

int Vector2::Distance(const Vector2& _krLHS, const Vector2& _krRHS) 
{
    float _fSqr = static_cast<float>((_krLHS.x-_krRHS.x)*(_krLHS.x-_krRHS.x) + (_krLHS.y-_krRHS.y)*(_krLHS.y-_krRHS.y));
	return static_cast<int>(sqrtf(_fSqr));
}

Vector2 Vector2::Normalize() 
{
    
	int _iMag = this->Magnitude();

    x /= _iMag;
    y /= _iMag;
    return *this;
}

int Vector2::Dot(const Vector2& _krRHS) const 
{
    return (x*_krRHS.x + y*_krRHS.y);
}

Vector2 operator*(const int _kiA, const Vector2 _krVec) 
{
    return Vector2(_kiA*_krVec.x, _kiA*_krVec.y);
}

std::ostream& operator<<(std::ostream& _rOS, const Vector2& _krVec) 
{
    _rOS << "(" << _krVec.x << ", " << _krVec.y << ", ";
    return _rOS;
}
// END OF Vector2 /////////////////////////////////////////////////////////////